package com.yuan.blog.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuan.blog.entity.InvitataionEntity;
import com.yuan.blog.mapper.InvitationMapper;
import com.yuan.blog.service.ICommentService;
import com.yuan.blog.service.IInvitataionService;
import com.yuan.blog.service.LikeService;
import com.yuan.blog.utils.TimeAgoUtils;
import com.yuan.blog.vo.IndexDataVo;
import com.yuan.blog.vo.InvitataionDataVo;
import com.yuan.blog.vo.InvitataionStatusVo;
import com.yuan.blog.vo.InvitationVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
@Slf4j
public class InvitataionServiceImpl extends ServiceImpl<InvitationMapper, InvitataionEntity> implements IInvitataionService {

    @Autowired
    private InvitationMapper invitationMapper;

    @Autowired
    private ICommentService commentService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private String invitataionKey = "blog:web:invitataion:%s";

    private Lock lock = new ReentrantLock();

    //解决缓存击穿问题
    @Override
    public InvitataionEntity getById(Serializable id) {

        String key = String.format(invitataionKey,id);
        //查询缓存
        String json = stringRedisTemplate.opsForValue().get(key);
        InvitataionEntity invitataionEntity = null;
        //判断缓存是否命中
        if (ObjectUtils.isEmpty(json)){
            lock.lock();
            try {
                json = stringRedisTemplate.opsForValue().get(key);
                if (ObjectUtils.isEmpty(json)){
                    //缓存没有命中,查询MySQL数据库
                    invitataionEntity = baseMapper.selectById(id);
                    log.error("在MySQL中查询帖字的数据");
                    json = JSON.toJSONString(invitataionEntity);
                    //将查到的数据放入缓存
                    stringRedisTemplate.opsForValue().set(key,json,5,TimeUnit.MINUTES);
                }else {
                    invitataionEntity =  JSON.parseObject(json,InvitataionEntity.class);
                }
            }finally {
                lock.unlock();
            }
        }else {
            invitataionEntity =  JSON.parseObject(json,InvitataionEntity.class);
        }
        return invitataionEntity;
    }

    @Override
    public List<IndexDataVo> indexDataList(Integer order) throws Exception {
        return invitationMapper.indexDataList(order);
    }

    @Override
    public Boolean updateType(InvitataionStatusVo vo) {
        InvitataionEntity invitataion = new InvitataionEntity();
        if (vo.getEntityType() == 1) {
            invitataion.setType(vo.getStatus());
        } else if (vo.getEntityType() == 2) {
            invitataion.setStatus(vo.getStatus());
        }
        invitataion.setId(vo.getEntityId());
        return invitationMapper.updateById(invitataion) > 0;
    }

    @Override
    public Map dataList(Page<InvitataionEntity> page) {

        HashMap<String, Object> map = new HashMap<>();

        // 1.创建一个集合
        List<InvitataionDataVo> voList = new ArrayList<>();

        // 2.查询所有的帖子
//        List<InvitataionEntity> entityList = baseMapper.selectList(null);
        Page<InvitataionEntity> entityPage = this.page(page);
        List<InvitataionEntity> entityList = entityPage.getRecords();


        // 3.遍历每个帖子，查询数据
        for (InvitataionEntity invitataionEntity : entityList) {
            InvitataionDataVo vo = new InvitataionDataVo();
            vo.setInvitataionEntity(invitataionEntity);
            // 评论查询MySQL
            vo.setCommentCount(commentService.getInvitationCommentSize(invitataionEntity.getId()));

            // 点赞数量查询redis
            vo.setLikeCount(likeService.getInvitataionLikeCount(1, invitataionEntity.getId()));

            // 查询帖子的预览量
            vo.setPvCount(likeService.getInvitataionPv(invitataionEntity.getId()));
            voList.add(vo);
        }
        long size = page.getSize();
        long current = page.getCurrent();
        long total = page.getTotal();
        long pages = page.getPages();
        map.put("InvitationDataVoList", voList);
        map.put("size",size);
        map.put("current",current);
        map.put("total",total);
        map.put("pages",pages);
        // 返回集合
        return map;

    }

    @Override
    public void indexDataPage(Page<IndexDataVo> page, Integer order) {
        invitationMapper.indexDataPage(page, order);

        List<IndexDataVo> records = page.getRecords();
        for (IndexDataVo indexDataVo : records) {
            // 把实体对象中的属性拷贝到vo对象中
            InvitationVo invitationVo = indexDataVo.getInvitationVo();
            invitationVo.setCreateTimeText(TimeAgoUtils.format(invitationVo.getCreateTime()));
        }
    }


}
